{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "JndnmDMp66FL"
   },
   "source": [
    "#### Copyright 2017 Google LLC."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "cellView": "both",
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "hMqWDc_m6rUC"
   },
   "outputs": [],
   "source": [
    "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "# you may not use this file except in compliance with the License.\n",
    "# You may obtain a copy of the License at\n",
    "#\n",
    "# https://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software\n",
    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "# See the License for the specific language governing permissions and\n",
    "# limitations under the License."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "P0bQXjp499sl"
   },
   "source": [
    "# 创建和操控张量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "I3BCiWJiCGsv"
   },
   "source": [
    "**学习目标：**\n",
    "  * 初始化 TensorFlow `Variable` 并赋值\n",
    "  * 创建和操控张量\n",
    "  * 回忆线性代数中的加法和乘法知识（如果这些内容对您来说很陌生，请参阅矩阵[加法](https://en.wikipedia.org/wiki/Matrix_addition)和[乘法](https://en.wikipedia.org/wiki/Matrix_multiplication)简介）\n",
    "  * 熟悉基本的 TensorFlow 数学和数组运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "85evKRsOIC5a"
   },
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "\n",
    "import tensorflow as tf\n",
    "try:\n",
    "  tf.contrib.eager.enable_eager_execution()\n",
    "  print(\"TF imported with eager execution!\")\n",
    "except ValueError:\n",
    "  print(\"TF already imported with eager execution!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "PT1sorfH-DdQ"
   },
   "source": [
    "## 矢量加法\n",
    "\n",
    "您可以对张量执行很多典型数学运算 ([TF API](https://www.tensorflow.org/api_guides/python/math_ops))。以下代码会创建下列矢量（一维张量），所有矢量都正好有六个元素：\n",
    "\n",
    "*  一个包含质数的 `primes` 矢量。\n",
    "*  一个值全为 `1` 的 `ones` 矢量。\n",
    "* 一个通过对前两个矢量执行元素级加法而创建的矢量。\n",
    "* 一个通过将 `primes` 矢量中的元素翻倍而创建的矢量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "ng37e6ur-GZo"
   },
   "outputs": [],
   "source": [
    "primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)\n",
    "print(\"primes:\", primes\n",
    ")\n",
    "ones = tf.ones([6], dtype=tf.int32)\n",
    "print(\"ones:\", ones)\n",
    "\n",
    "just_beyond_primes = tf.add(primes, ones)\n",
    "print(\"just_beyond_primes:\", just_beyond_primes)\n",
    "\n",
    "twos = tf.constant([2, 2, 2, 2, 2, 2], dtype=tf.int32)\n",
    "primes_doubled = primes * twos\n",
    "print(\"primes_doubled:\", primes_doubled)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "whbEUNguEAt2"
   },
   "source": [
    "输出张量不仅会返回其值，还会返回其形状（将在下一部分中讨论）以及存储在张量中的值的类型。调用张量的 `numpy` 方法会返回该张量的值（以 NumPy 数组形式）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "Dz4i5c88GRwJ"
   },
   "outputs": [],
   "source": [
    "some_matrix = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.int32)\n",
    "print(some_matrix)\n",
    "print(\"\\nvalue of some_matrix is:\\n\", some_matrix.numpy())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "fVvaXzzMGZid"
   },
   "source": [
    "### 张量形状\n",
    "\n",
    "形状用于描述张量维度的大小和数量。张量的形状表示为 `list`，其中第 `i` 个元素表示维度 `i` 的大小。列表的长度表示张量的阶（即维数）。\n",
    "\n",
    "有关详情，请参阅 [TensorFlow 文档](https://www.tensorflow.org/programmers_guide/tensors#shape)。\n",
    "\n",
    "以下是一些基本示例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "PWzvJnIAH_cF"
   },
   "outputs": [],
   "source": [
    "# A scalar (0-D tensor).\n",
    "scalar = tf.zeros([])\n",
    "\n",
    "# A vector with 3 elements.\n",
    "vector = tf.zeros([3])\n",
    "\n",
    "# A matrix with 2 rows and 3 columns.\n",
    "matrix = tf.zeros([2, 3])\n",
    "\n",
    "print('scalar has shape', scalar.get_shape(), 'and value:\\n', scalar.numpy())\n",
    "print('vector has shape', vector.get_shape(), 'and value:\\n', vector.numpy())\n",
    "print('matrix has shape', matrix.get_shape(), 'and value:\\n', matrix.numpy())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "musamrLavR5S"
   },
   "source": [
    "### 广播\n",
    "\n",
    "在数学中，您只能对形状相同的张量执行元素级运算（例如，*相加*和*等于*）。不过，在 TensorFlow 中，您可以对张量执行传统意义上不可行的运算。TensorFlow 支持**广播**（一种借鉴自 NumPy 的概念）。利用广播，元素级运算中的较小数组会增大到与较大数组具有相同的形状。例如，通过广播：\n",
    "\n",
    "* 如果运算需要大小为 `[6]` 的张量，则大小为 `[1]` 或 `[]` 的张量可以作为运算数。\n",
    "* 如果运算需要大小为 `[4, 6]` 的张量，则以下任何大小的张量都可以作为运算数：\n",
    "  * `[1, 6]`\n",
    "  * `[6]`\n",
    "  * `[]`\n",
    "* 如果运算需要大小为 `[3, 5, 6]` 的张量，则以下任何大小的张量都可以作为运算数：\n",
    "\n",
    "  * `[1, 5, 6]`\n",
    "  * `[3, 1, 6]`\n",
    "  * `[3, 5, 1]`\n",
    "  * `[1, 1, 1]`\n",
    "  * `[5, 6]`\n",
    "  * `[1, 6]`\n",
    "  * `[6]`\n",
    "  * `[1]`\n",
    "  * `[]`\n",
    "\n",
    "**注意：**当张量被广播时，从概念上来说，系统会**复制**其条目（出于性能考虑，实际并不复制。广播专为实现性能优化而设计）。\n",
    "\n",
    "有关完整的广播规则集，请参阅简单易懂的 [NumPy 广播文档](http://docs.scipy.org/doc/numpy-1.10.1/user/basics.broadcasting.html)。\n",
    "\n",
    "以下代码执行了与之前一样的张量运算，不过使用的是标量值（而不是全包含 `1` 或全包含 `2` 的矢量）和广播。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "7lys_BeLy2SD"
   },
   "outputs": [],
   "source": [
    "primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)\n",
    "print(\"primes:\", primes)\n",
    "\n",
    "one = tf.constant(1, dtype=tf.int32)\n",
    "print(\"one:\", one)\n",
    "\n",
    "just_beyond_primes = tf.add(primes, one)\n",
    "print(\"just_beyond_primes:\", just_beyond_primes)\n",
    "\n",
    "two = tf.constant(2, dtype=tf.int32)\n",
    "primes_doubled = primes * two\n",
    "print(\"primes_doubled:\", primes_doubled)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "FPBzBzRROxwe"
   },
   "source": [
    "### 练习 1：矢量运算。\n",
    "\n",
    "执行矢量运算以创建一个“just_under_primes_squared”矢量，其中第 `i` 个元素等于 `primes` 中第 `i` 个元素的平方减 1。例如，第二个元素为 `3 * 3 - 1 = 8`。\n",
    "\n",
    "使用 `tf.multiply` 或 `tf.pow` 操作可求得 `primes` 矢量中每个元素值的平方。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "pWK2rAttQlD6"
   },
   "outputs": [],
   "source": [
    "# Write your code for Task 1 here."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "7d1kfAx4QL17"
   },
   "source": [
    "### 解决方案\n",
    "\n",
    "点击下方，查看解决方案。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "QUgHSI9BOUx7"
   },
   "outputs": [],
   "source": [
    "# Task: Square each element in the primes vector, then subtract 1.\n",
    "\n",
    "def solution(primes):\n",
    "  primes_squared = tf.multiply(primes, primes)\n",
    "  neg_one = tf.constant(-1, dtype=tf.int32)\n",
    "  just_under_primes_squared = tf.add(primes_squared, neg_one)\n",
    "  return just_under_primes_squared\n",
    "\n",
    "def alternative_solution(primes):\n",
    "  primes_squared = tf.pow(primes, 2)\n",
    "  one = tf.constant(1, dtype=tf.int32)\n",
    "  just_under_primes_squared = tf.subtract(primes_squared, one)\n",
    "  return just_under_primes_squared\n",
    "\n",
    "primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)\n",
    "just_under_primes_squared = solution(primes)\n",
    "print(\"just_under_primes_squared:\", just_under_primes_squared)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "it0P-AV0-Jb4"
   },
   "source": [
    "## 矩阵乘法\n",
    "\n",
    "在线性代数中，当两个矩阵相乘时，第一个矩阵的*列*数必须等于第二个矩阵的*行*数。\n",
    "\n",
    "- `3x4` 矩阵乘以 `4x2` 矩阵是**_有效_**的，可以得出一个 `3x2` 矩阵。\n",
    "- `4x2` 矩阵乘以 `3x4` 矩阵是*_无效_**的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "OVR8QPif-MeS"
   },
   "outputs": [],
   "source": [
    "# A 3x4 matrix (2-d tensor).\n",
    "x = tf.constant([[5, 2, 4, 3], [5, 1, 6, -2], [-1, 3, -1, -2]],\n",
    "                dtype=tf.int32)\n",
    "\n",
    "# A 4x2 matrix (2-d tensor).\n",
    "y = tf.constant([[2, 2], [3, 5], [4, 5], [1, 6]], dtype=tf.int32)\n",
    "\n",
    "# Multiply `x` by `y`; result is 3x2 matrix.\n",
    "matrix_multiply_result = tf.matmul(x, y)\n",
    "\n",
    "print(matrix_multiply_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "fziRnmuy-O9x"
   },
   "source": [
    "## 张量变形\n",
    "\n",
    "由于张量加法和矩阵乘法均对运算数施加了限制条件，TensorFlow 编程者需要频繁改变张量的形状。\n",
    "\n",
    "您可以使用 `tf.reshape` 方法改变张量的形状。\n",
    "例如，您可以将 8x2 张量变形为 2x8 张量或 4x4 张量："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "L05ob6a_G77m"
   },
   "outputs": [],
   "source": [
    "# Create an 8x2 matrix (2-D tensor).\n",
    "matrix = tf.constant(\n",
    "    [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16]],\n",
    "    dtype=tf.int32)\n",
    "\n",
    "reshaped_2x8_matrix = tf.reshape(matrix, [2, 8])\n",
    "reshaped_4x4_matrix = tf.reshape(matrix, [4, 4])\n",
    "\n",
    "print(\"Original matrix (8x2):\")\n",
    "print(matrix.numpy())\n",
    "print(\"Reshaped matrix (2x8):\")\n",
    "print(reshaped_2x8_matrix.numpy())\n",
    "print(\"Reshaped matrix (4x4):\")\n",
    "print(reshaped_4x4_matrix.numpy())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "b6cFa92YGyU5"
   },
   "source": [
    "\n",
    "此外，您还可以使用 `tf.reshape` 更改张量的维数（“阶”）。\n",
    "例如，您可以将 8x2 张量变形为三维 2x2x4 张量或一维 16 元素张量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "3MpcwWj9-Sqp"
   },
   "outputs": [],
   "source": [
    "# Create an 8x2 matrix (2-D tensor).\n",
    "matrix = tf.constant(\n",
    "    [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16]],\n",
    "    dtype=tf.int32)\n",
    "\n",
    "reshaped_2x2x4_tensor = tf.reshape(matrix, [2, 2, 4])\n",
    "one_dimensional_vector = tf.reshape(matrix, [16])\n",
    "\n",
    "print(\"Original matrix (8x2):\")\n",
    "print(matrix.numpy())\n",
    "print(\"Reshaped 3-D tensor (2x2x4):\")\n",
    "print(reshaped_2x2x4_tensor.numpy())\n",
    "print(\"1-D vector:\")\n",
    "print(one_dimensional_vector.numpy())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "CrpowaWo-VLq"
   },
   "source": [
    "### 练习 2：改变两个张量的形状，使其能够相乘。\n",
    "\n",
    "下面两个矢量无法进行矩阵乘法运算：\n",
    "\n",
    "  *  `a = tf.constant([5, 3, 2, 7, 1, 4])`\n",
    "  *  `b = tf.constant([4, 6, 3])`\n",
    "\n",
    "请改变这两个矢量的形状，使其成为可以进行矩阵乘法运算的运算数。\n",
    "然后，对变形后的张量调用矩阵乘法运算。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "p6idvaeK-Zxq"
   },
   "outputs": [],
   "source": [
    "# Write your code for Task 2 here."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "EYzU56M4MG_x"
   },
   "source": [
    "### 解决方案\n",
    "\n",
    "点击下方，查看解决方案。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "F9HDdiugJKpH"
   },
   "source": [
    "请注意，当两个矩阵相乘时，第一个矩阵的*列*数必须等于第二个矩阵的*行*数。\n",
    "\n",
    "一个可行的解决方案是，将 `a` 变形为 2x3 矩阵，并将 `b` 变形为 3x1 矩阵，从而在相乘后得到一个 2x1 矩阵："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "8Sef4d0SMMtk"
   },
   "outputs": [],
   "source": [
    "# Task: Reshape two tensors in order to multiply them\n",
    "\n",
    "a = tf.constant([5, 3, 2, 7, 1, 4])\n",
    "b = tf.constant([4, 6, 3])\n",
    "\n",
    "reshaped_a = tf.reshape(a, [2, 3])\n",
    "reshaped_b = tf.reshape(b, [3, 1])\n",
    "c = tf.matmul(reshaped_a, reshaped_b)\n",
    "\n",
    "print(\"reshaped_a (2x3):\")\n",
    "print(reshaped_a.numpy())\n",
    "print(\"reshaped_b (3x1):\")\n",
    "print(reshaped_b.numpy())\n",
    "print(\"reshaped_a x reshaped_b (2x1):\")\n",
    "print(c.numpy())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "uDZSacTxJ0XG"
   },
   "source": [
    "还有一个解决方案是，将 `a` 变形为 6x1 矩阵，并将 `b` 变形为 1x3 矩阵，从而在相乘后得到一个 6x3 矩阵。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "x1JYo7iE2oKk"
   },
   "source": [
    "## 变量、初始化和赋值\n",
    "\n",
    "到目前为止，我们执行的所有运算都针对的是静态值 (`tf.constant`)；调用 `numpy()` 始终返回同一结果。在 TensorFlow 中可以定义 `Variable` 对象，它的值是可以更改的。\n",
    "\n",
    "创建变量时，您可以明确设置一个初始值，也可以使用初始化程序（例如分布）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "6opLnjfD3PdL"
   },
   "outputs": [],
   "source": [
    "# Create a scalar variable with the initial value 3.\n",
    "v = tf.contrib.eager.Variable([3])\n",
    "\n",
    "# Create a vector variable of shape [1, 4], with random initial values,\n",
    "# sampled from a normal distribution with mean 1 and standard deviation 0.35.\n",
    "w = tf.contrib.eager.Variable(tf.random_normal([1, 4], mean=1.0, stddev=0.35))\n",
    "\n",
    "print(\"v:\", v.numpy())\n",
    "print(\"w:\", w.numpy())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "yrZ31hPw66uy"
   },
   "source": [
    "要更改变量的值，请使用 `assign` 操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "zD0D1DCR7NBX"
   },
   "outputs": [],
   "source": [
    "v = tf.contrib.eager.Variable([3])\n",
    "print(v.numpy())\n",
    "\n",
    "tf.assign(v, [7])\n",
    "print(v.numpy())\n",
    "\n",
    "v.assign([5])\n",
    "print(v.numpy())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "HQvQCZvuLKfY"
   },
   "source": [
    "向变量赋予新值时，其形状必须和之前的形状一致："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "AoSJFAlkLHTX"
   },
   "outputs": [],
   "source": [
    "v = tf.contrib.eager.Variable([[1, 2, 3], [4, 5, 6]])\n",
    "print(v.numpy())\n",
    "\n",
    "try:\n",
    "  print(\"Assigning [7, 8, 9] to v\")\n",
    "  v.assign([7, 8, 9])\n",
    "except ValueError as e:\n",
    "  print(\"Exception:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "tB78Zq4h78Zr"
   },
   "source": [
    "还有很多关于变量的内容我们并未在这里提及，例如加载和存储。要了解详情，请参阅 [TensorFlow 文档](https://www.tensorflow.org/programmers_guide/variables)。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "iFIOcnfz_Oqw"
   },
   "source": [
    "### 练习 3：模拟投掷两个骰子 10 次。\n",
    "\n",
    "创建一个骰子模拟，在模拟中生成一个 `10x3` 二维张量，其中：\n",
    "\n",
    "  * 列 `1` 和 `2` 均存储一个六面骰子（值为 1-6）的一次投掷值。\n",
    "  * 列 `3` 存储同一行中列 `1` 和 `2` 的值的总和。\n",
    "\n",
    "例如，第一行中可能会包含以下值：\n",
    "\n",
    "  * 列 `1` 存储 `4`\n",
    "  * 列 `2` 存储 `3`\n",
    "  * 列 `3` 存储 `7`\n",
    "\n",
    "要完成此任务，您需要浏览 [TensorFlow 文档](https://www.tensorflow.org/api_guides/python/array_ops)。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "ocwT0iXH-nhT"
   },
   "outputs": [],
   "source": [
    "# Write your code for Task 3 here."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Kt7aojXkR_qS"
   },
   "source": [
    "### 解决方案\n",
    "\n",
    "点击下方，查看解决方案。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "6kRkwXE1MHVS"
   },
   "source": [
    "我们将投掷骰子得到的值分别放入两个 10x1 矩阵中，即 `die1` 和 `die2`。两次投掷骰子得到的值的总和将存储在 `dice_sum` 中，然后，将三个 10x1 矩阵*连接*成一个矩阵，从而创建一个 10x3 矩阵。\n",
    "\n",
    "或者，我们可以将投掷骰子得到的值放入一个 10x2 矩阵中，但将同一矩阵的不同列相加会更加复杂。我们还可以将投掷骰子得到的值放入两个一维张量（矢量）中，但这样做需要转置结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "6UUluecQSCvr"
   },
   "outputs": [],
   "source": [
    "# Task: Simulate 10 throws of two dice. Store the results in a 10x3 matrix.\n",
    "\n",
    "die1 = tf.contrib.eager.Variable(\n",
    "    tf.random_uniform([10, 1], minval=1, maxval=7, dtype=tf.int32))\n",
    "die2 = tf.contrib.eager.Variable(\n",
    "    tf.random_uniform([10, 1], minval=1, maxval=7, dtype=tf.int32))\n",
    "\n",
    "dice_sum = tf.add(die1, die2)\n",
    "resulting_matrix = tf.concat(values=[die1, die2, dice_sum], axis=1)\n",
    "\n",
    "print(resulting_matrix.numpy())"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [
    "JndnmDMp66FL",
    "7d1kfAx4QL17",
    "EYzU56M4MG_x",
    "Kt7aojXkR_qS"
   ],
   "default_view": {},
   "name": "creating_and_manipulating_tensors.ipynb",
   "provenance": [],
   "version": "0.3.2",
   "views": {}
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
